<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>业务办理登记弹窗</title>
    <style>
        body {
            font-family: Arial, sans-serif;
            margin: 0;
            padding: 20px;
            background-color: #f5f5f5;
        }
        
        .demo-container {
            max-width: 800px;
            margin: 0 auto;
            background: #fff;
            padding: 30px;
            border-radius: 8px;
            box-shadow: 0 2px 12px rgba(0, 0, 0, 0.1);
        }
        
        h1 {
            text-align: center;
            color: #303133;
            margin-bottom: 30px;
        }
        
        .button-group {
            display: flex;
            justify-content: center;
            gap: 20px;
            margin-bottom: 30px;
        }
        
        .demo-btn {
            padding: 12px 24px;
            border: none;
            border-radius: 4px;
            cursor: pointer;
            font-size: 14px;
            transition: all 0.3s;
            color: #fff;
        }
        
        .demo-btn.primary {
            background-color: #409eff;
        }
        
        .demo-btn.success {
            background-color: #67c23a;
        }
        
        .demo-btn.warning {
            background-color: #e6a23c;
        }
        
        .demo-btn:hover {
            opacity: 0.8;
            transform: translateY(-2px);
        }
        
        /* 弹窗组件样式 */
        .dialog-overlay {
            position: fixed;
            top: 0;
            left: 0;
            width: 100%;
            height: 100%;
            background-color: rgba(0, 0, 0, 0.5);
            z-index: 2000;
            display: none;
        }
        
        .dialog-overlay.show {
            display: flex;
            align-items: center;
            justify-content: center;
        }
        
        .dialog {
            position: relative;
            background: #fff;
            border-radius: 8px;
            box-shadow: 0 8px 32px rgba(0, 0, 0, 0.12);
            width: 1000px;
            max-width: 95%;
            max-height: 90%;
            overflow: hidden;
            transform: scale(0.7);
            opacity: 0;
            transition: all 0.3s;
        }
        
        .dialog.show {
            transform: scale(1);
            opacity: 1;
        }
        
        .dialog-header {
            padding: 20px 20px 10px;
            border-bottom: 1px solid #ebeef5;
        }
        
        .dialog-header .dialog-title {
            line-height: 24px;
            font-size: 18px;
            color: #303133;
            margin: 0;
        }
        
        .dialog-header .dialog-close {
            position: absolute;
            top: 12px;
            right: 20px;
            padding: 0;
            background: none;
            border: none;
            outline: none;
            cursor: pointer;
            font-size: 26px;
            color: #909399;
        }
        
        .dialog-header .dialog-close:hover {
            color: #409eff;
        }
        
        .dialog-body {
            padding: 30px 20px;
            color: #606266;
            font-size: 14px;
            word-break: break-all;
            max-height: 60vh;
            overflow-y: auto;
        }
        
        .dialog-body::-webkit-scrollbar {
            width: 6px;
        }
        
        .dialog-body::-webkit-scrollbar-track {
            background: #f1f1f1;
            border-radius: 3px;
        }
        
        .dialog-body::-webkit-scrollbar-thumb {
            background: #c1c1c1;
            border-radius: 3px;
        }
        
        .dialog-body::-webkit-scrollbar-thumb:hover {
            background: #a8a8a8;
        }
        
        .dialog-footer {
            padding: 10px 20px 20px;
            text-align: right;
            box-sizing: border-box;
            border-top: 1px solid #ebeef5;
        }
        
        .dialog-footer .dialog-btn {
            display: inline-block;
            line-height: 1;
            white-space: nowrap;
            cursor: pointer;
            border: 1px solid #dcdfe6;
            color: #606266;
            text-align: center;
            box-sizing: border-box;
            outline: none;
            margin: 0;
            transition: 0.1s;
            font-weight: 500;
            padding: 12px 20px;
            font-size: 14px;
            border-radius: 4px;
            margin-left: 10px;
        }
        
        .dialog-footer .dialog-btn:hover {
            color: #409eff;
            border-color: #c6e2ff;
            background-color: #ecf5ff;
        }
        
        .dialog-footer .dialog-btn.primary {
            color: #fff;
            background-color: #409eff;
            border-color: #409eff;
        }
        
        .dialog-footer .dialog-btn.primary:hover {
            background: #66b1ff;
            border-color: #66b1ff;
            color: #fff;
        }
        
        /* 弹窗内表格样式 */
        .dialog-table {
            width: 100%;
            border-collapse: collapse;
            border-spacing: 0;
            border: 1px solid #ebeef5;
            border-radius: 6px;
            overflow: hidden;
        }
        
        .dialog-table th,
        .dialog-table td {
            border-bottom: 1px solid #ebeef5;
            padding: 16px 12px;
            text-align: left;
            font-size: 14px;
        }
        
        .dialog-table th:last-child,
        .dialog-table td:last-child {
            width: 80px;
            text-align: center;
            padding: 12px 8px;
        }
        
        .dialog-table th {
            color: #303133;
            font-weight: 600;
            background: linear-gradient(135deg, #f8f9fa 0%, #e9ecef 100%);
            border-bottom: 2px solid #409eff;
        }
        
        .dialog-table td {
            color: #606266;
            background-color: #fff;
            transition: background-color 0.2s;
        }
        
        .dialog-table tbody tr:hover td {
            background-color: #f5f7fa;
        }
        
        .dialog-table tbody tr:last-child td {
            border-bottom: none;
        }
        
        .dialog-table .table-input {
            width: 100%;
            min-height: 32px;
            padding: 3px 12px;
            border: 1px solid #dcdfe6;
            border-radius: 4px;
            font-size: 14px;
            color: #606266;
            background-color: #fff;
            transition: border-color 0.2s;
        }
        
        .dialog-table .table-input:focus {
            outline: none;
            border-color: #409eff;
        }
        
        .dialog-table .table-input::placeholder {
            color: #c0c4cc;
        }
        
        .delete-btn {
            background: linear-gradient(135deg, #f56c6c 0%, #f78989 100%);
            color: #fff;
            border: none;
            padding: 6px 12px;
            border-radius: 4px;
            cursor: pointer;
            font-size: 12px;
            transition: all 0.3s;
            box-shadow: 0 2px 4px rgba(245, 108, 108, 0.3);
        }
        
        .delete-btn:hover {
            background: linear-gradient(135deg, #f78989 0%, #f56c6c 100%);
            transform: translateY(-1px);
            box-shadow: 0 4px 8px rgba(245, 108, 108, 0.4);
        }
        
        .delete-btn:active {
            transform: translateY(0);
        }
        
        .add-row-btn {
            width: 100%;
            padding: 12px 20px;
            margin-top: 16px;
            background: linear-gradient(135deg, #409eff 0%, #66b1ff 100%);
            color: #fff;
            border: 1px solid #409eff;
            border-radius: 6px;
            cursor: pointer;
            font-size: 14px;
            font-weight: 500;
            transition: all 0.3s;
            box-shadow: 0 4px 12px rgba(64, 158, 255, 0.3);
        }
        
        .add-row-btn:hover {
            background: linear-gradient(135deg, #66b1ff 0%, #409eff 100%);
            border-color: #66b1ff;
            transform: translateY(-2px);
            box-shadow: 0 6px 16px rgba(64, 158, 255, 0.4);
        }
        
        .add-row-btn:active {
            transform: translateY(0);
        }
        
        .empty-state {
            text-align: center;
            padding: 40px 0;
            color: #909399;
            font-size: 14px;
        }
        
        /* 树形下拉组件样式 */
        .tree-select {
            position: relative;
            display: inline-block;
            width: 100%;
        }
        
        .tree-select-trigger {
            display: flex;
            align-items: center;
            justify-content: space-between;
            padding: 3px 12px;
            border: 1px solid #d9d9d9;
            border-radius: 4px;
            background: #fff;
            cursor: pointer;
            min-height: 32px;
            transition: all 0.3s;
        }
        
        .tree-select-trigger:hover {
            border-color: #40a9ff;
        }
        
        .tree-select-trigger.active {
            border-color: #1890ff;
            box-shadow: 0 0 0 2px rgba(24, 144, 255, 0.2);
        }
        
        .tree-select-placeholder {
            color: #bfbfbf;
        }
        
        .tree-select-value {
            color: #262626;
            flex: 1;
            overflow: hidden;
            text-overflow: ellipsis;
            white-space: nowrap;
        }
        
        .tree-select-arrow {
            width: 0;
            height: 0;
            border-left: 4px solid transparent;
            border-right: 4px solid transparent;
            border-top: 4px solid #bfbfbf;
            transition: transform 0.3s;
            margin-left: 8px;
        }
        
        .tree-select-trigger.active .tree-select-arrow {
            transform: rotate(180deg);
        }
        
        .tree-select-dropdown {
            position: fixed;
            background: #fff;
            border: 1px solid #d9d9d9;
            border-radius: 4px;
            box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15);
            z-index: 9999;
            max-height: 256px;
            overflow: hidden;
            display: none;
        }
        
        .tree-select-dropdown.show {
            display: block;
        }
        
        .tree-select-search {
            padding: 8px;
            border-bottom: 1px solid #f0f0f0;
        }
        
        .tree-select-search input {
            width: 100%;
            padding: 4px 8px;
            border: 1px solid #d9d9d9;
            border-radius: 4px;
            outline: none;
            font-size: 14px;
        }
        
        .tree-select-search input:focus {
            border-color: #1890ff;
            box-shadow: 0 0 0 2px rgba(24, 144, 255, 0.2);
        }
        
        .tree-select-options {
            max-height: 200px;
            overflow-y: auto;
        }
        
        .tree-select-option {
            padding: 8px 12px;
            cursor: pointer;
            transition: background-color 0.3s;
            display: flex;
            align-items: center;
        }
        
        .tree-select-option:hover {
            background-color: #f5f5f5;
        }
        
        .tree-select-option.selected {
            background-color: #e6f7ff;
            color: #1890ff;
        }
        
        .tree-select-option.disabled {
            color: #bfbfbf;
            cursor: not-allowed;
            background-color: #fafafa;
        }
        
        .tree-select-option.disabled:hover {
            background-color: #fafafa;
        }
        
        .tree-select-option-indent {
            width: 20px;
            flex-shrink: 0;
        }
        
        .tree-select-option-content {
            flex: 1;
            overflow: hidden;
            text-overflow: ellipsis;
            white-space: nowrap;
        }
        
        .tree-select-option-level-0 {
            font-weight: 600;
            color: #262626;
        }
        
        .tree-select-option-level-1 {
            color: #595959;
        }
        
        .tree-select-empty {
            padding: 16px;
            text-align: center;
            color: #bfbfbf;
        }
    </style>
</head>
<body>
    <div class="demo-container">
        <h1>业务办理登记弹窗组件</h1>
        
        <div class="button-group">
            <button class="demo-btn primary" onclick="openBusinessDialog('办结')">办结业务登记</button>
            <button class="demo-btn success" onclick="openBusinessDialog('受理')">受理业务登记</button>
        </div>
        
        <p style="text-align: center; color: #666; margin-top: 20px;">
            点击上方按钮打开不同类型的业务登记弹窗
        </p>
    </div>

    <!-- 弹窗组件 -->
    <div class="dialog-overlay" id="businessDialog">
        <div class="dialog">
            <div class="dialog-header">
                <h3 class="dialog-title">办理业务登记</h3>
                <button class="dialog-close" onclick="closeDialog()">&times;</button>
            </div>
            <div class="dialog-body">
                <table class="dialog-table" id="businessTable">
                    <thead>
                        <tr>
                            <th style="width: 45%;">办理业务</th>
                            <th style="width: 30%;">实际办理量</th>
                            <th style="width: 15%;">操作</th>
                        </tr>
                    </thead>
                    <tbody id="businessTableBody">
                        <!-- 动态添加的行将在这里 -->
                    </tbody>
                </table>
                <div class="empty-state" id="emptyState" style="display: none;">
                    暂无数据，请点击下方按钮添加业务
                </div>
                <button class="add-row-btn" onclick="addTableRow()">+ 新增业务</button>
            </div>
            <div class="dialog-footer">
                <button class="dialog-btn" onclick="cancelDialog()">取消</button>
                <button class="dialog-btn primary" onclick="confirmDialog()">确定</button>
            </div>
        </div>
    </div>

    <script>
        // 全局变量
        var businessData = [];
        var rowCounter = 0;
        var currentDialogType = '';
        
        // 树形数据
        var treeData = [
            {
                name: '人事服务',
                id: '432432432',
                services: [
                    {
                        name: '人事档案查询',
                        id: '4324321'
                    },
                    {
                        name: '工资证明开具',
                        id: '4324322'
                    },
                    {
                        name: '在职证明开具',
                        id: '4324323'
                    },
                    {
                        name: '职称评定申请',
                        id: '4324324'
                    }
                ]
            },
            {
                name: '教务服务',
                id: '432432433',
                services: [
                    {
                        name: '学籍证明开具',
                        id: '4324325'
                    },
                    {
                        name: '成绩查询',
                        id: '4324326'
                    },
                    {
                        name: '证书申请',
                        id: '4324327'
                    }
                ]
            },
            {
                name: '学务服务',
                id: '432432434',
                services: [
                    {
                        name: '转专业申请',
                        id: '4324328'
                    },
                    {
                        name: '休学申请',
                        id: '4324329'
                    },
                    {
                        name: '复学申请',
                        id: '4324330'
                    },
                    {
                        name: '退学申请',
                        id: '4324331'
                    },
                    {
                        name: '毕业申请',
                        id: '4324332'
                    }
                ]
            }
        ];
        
        // 打开弹窗
        function openBusinessDialog(type) {
            currentDialogType = type;
            const dialog = document.getElementById('businessDialog');
            const dialogElement = dialog.querySelector('.dialog');
            
            // 更新弹窗标题
            dialog.querySelector('.dialog-title').textContent = type + '业务登记';
            
            // 显示弹窗
            dialog.classList.add('show');
            setTimeout(() => {
                dialogElement.classList.add('show');
            }, 10);
            
            // 初始化表格
            updateTableDisplay();
        }
        
        // 关闭弹窗
        function closeDialog() {
            const dialog = document.getElementById('businessDialog');
            const dialogElement = dialog.querySelector('.dialog');
            
            dialogElement.classList.remove('show');
            setTimeout(() => {
                dialog.classList.remove('show');
            }, 300);
        }
        
        // 添加表格行
        function addTableRow() {
            rowCounter++;
            const newRow = {
                id: 'row_' + rowCounter,
                business: '',
                amount: ''
            };
            businessData.push(newRow);
            updateTableDisplay();
        }
        
        // 删除表格行
        function deleteTableRow(rowId) {
            businessData = businessData.filter(item => item.id !== rowId);
            updateTableDisplay();
        }
        
        // 创建树形下拉组件
        function createTreeSelect(rowId, selectedValue) {
            const selectId = 'tree-select-' + rowId;
            const dropdownId = 'tree-dropdown-' + rowId;
            
            // 创建下拉菜单并插入到body中
            setTimeout(() => {
                if (!document.getElementById(dropdownId)) {
                    const dropdown = document.createElement('div');
                    dropdown.className = 'tree-select-dropdown';
                    dropdown.id = dropdownId;
                    dropdown.style.position = 'fixed';
                    dropdown.innerHTML = '<div class="tree-select-search">' +
                            '<input type="text" placeholder="搜索业务..." oninput="filterTreeOptions(\'' + rowId + '\', this.value)">' +
                        '</div>' +
                        '<div class="tree-select-options" id="tree-options-' + rowId + '">' +
                            renderTreeOptions(rowId) +
                        '</div>';
                    document.body.appendChild(dropdown);
                }
            }, 0);
            
            return '<div class="tree-select" id="' + selectId + '">' +
                '<div class="tree-select-trigger" onclick="toggleTreeDropdown(\'' + rowId + '\')">' +
                    '<span class="tree-select-value">' + (selectedValue || '<span class="tree-select-placeholder">请选择业务类型</span>') + '</span>' +
                    '<div class="tree-select-arrow"></div>' +
                '</div>' +
            '</div>';
        }
        
        // 渲染树形选项
        function renderTreeOptions(rowId, searchText) {
            searchText = searchText || '';
            let html = '';
            
            treeData.forEach(category => {
                const filteredServices = category.services.filter(service => 
                    !searchText || service.name.toLowerCase().includes(searchText.toLowerCase())
                );
                
                if (!searchText || filteredServices.length > 0) {
                    // 一级分类（不可选）
                    html += '<div class="tree-select-option tree-select-option-level-0 disabled">';
                    html += '<div class="tree-select-option-indent"></div>';
                    html += '<div class="tree-select-option-content">' + category.name + '</div>';
                    html += '</div>';
                    
                    // 二级服务（可选）
                    filteredServices.forEach(service => {
                        html += '<div class="tree-select-option tree-select-option-level-1" onclick="selectTreeOption(\'' + rowId + '\', \'' + service.id + '\', \'' + service.name + '\')">';
                        html += '<div class="tree-select-option-indent"></div>';
                        html += '<div class="tree-select-option-content">' + service.name + '</div>';
                        html += '</div>';
                    });
                }
            });
            
            return html || '<div class="tree-select-empty">暂无匹配的业务类型</div>';
        }
        
        // 切换下拉框显示
        function toggleTreeDropdown(rowId) {
            const dropdown = document.getElementById('tree-dropdown-' + rowId);
            const trigger = document.querySelector('#tree-select-' + rowId + ' .tree-select-trigger');
            const isVisible = dropdown && dropdown.classList.contains('show');
            
            // 关闭所有其他下拉框
            document.querySelectorAll('.tree-select-dropdown').forEach(d => {
                d.classList.remove('show');
            });
            document.querySelectorAll('.tree-select-trigger').forEach(t => {
                t.classList.remove('active');
            });
            
            // 切换当前下拉框
            if (!isVisible && dropdown) {
                // 计算触发器位置 - 显示在触发器正下方并紧挨着
                const triggerRect = trigger.getBoundingClientRect();
                dropdown.style.top = triggerRect.bottom + 'px';
                dropdown.style.left = triggerRect.left + 'px';
                dropdown.style.width = triggerRect.width + 'px';
                
                dropdown.classList.add('show');
                trigger.classList.add('active');
            }
        }
        
        // 选择树形选项
        function selectTreeOption(rowId, serviceId, serviceName) {
            const selectContainer = document.getElementById('tree-select-' + rowId);
            const textElement = selectContainer.querySelector('.tree-select-value');
            const dropdown = document.getElementById('tree-dropdown-' + rowId);
            const trigger = selectContainer.querySelector('.tree-select-trigger');
            
            textElement.textContent = serviceName;
            if (dropdown) {
                dropdown.classList.remove('show');
            }
            if (trigger) {
                trigger.classList.remove('active');
            }
            
            // 更新业务数据
            updateBusinessData(rowId, 'business', serviceName);
            updateBusinessData(rowId, 'businessId', serviceId);
        }
        
        // 过滤树形选项
        function filterTreeOptions(rowId, searchText) {
            const optionsContainer = document.getElementById('tree-options-' + rowId);
            if (optionsContainer) {
                optionsContainer.innerHTML = renderTreeOptions(rowId, searchText);
            }
        }
        
        // 点击外部关闭下拉框
        document.addEventListener('click', function(e) {
            if (!e.target.closest('.tree-select') && !e.target.closest('.tree-select-dropdown')) {
                document.querySelectorAll('.tree-select-dropdown').forEach(d => {
                    d.classList.remove('show');
                });
                document.querySelectorAll('.tree-select-trigger').forEach(t => {
                    t.classList.remove('active');
                });
            }
        });
        
        // 阻止搜索框点击事件冒泡
        document.addEventListener('click', function(e) {
            if (e.target.closest('.tree-select-search input')) {
                e.stopPropagation();
            }
        });
        
        // 更新表格显示
        function updateTableDisplay() {
            const tbody = document.getElementById('businessTableBody');
            const emptyState = document.getElementById('emptyState');
            
            if (businessData.length === 0) {
                tbody.innerHTML = '';
                emptyState.style.display = 'block';
            } else {
                emptyState.style.display = 'none';
                tbody.innerHTML = businessData.map(function(row) {
                    return '<tr>' +
                        '<td>' +
                            createTreeSelect(row.id, row.business) +
                        '</td>' +
                        '<td>' +
                            '<input type="number" class="table-input" placeholder="请输入办理量" ' +
                                   'value="' + row.amount + '" min="1" ' +
                                   'onchange="updateBusinessData(\'' + row.id + '\', \'amount\', this.value)">' +
                        '</td>' +
                        '<td>' +
                            '<button class="delete-btn" onclick="deleteTableRow(\'' + row.id + '\')">' + '删除' + '</button>' +
                        '</td>' +
                    '</tr>';
                }).join('');
            }
        }
        
        // 更新业务数据
        function updateBusinessData(rowId, field, value) {
            const row = businessData.find(item => item.id === rowId);
            if (row) {
                row[field] = value;
            }
        }
        
        // 取消按钮
        function cancelDialog() {
            // 清空数据
            businessData = [];
            rowCounter = 0;
            currentDialogType = '';
            
            // 关闭弹窗
            closeDialog();
        }
        
        // 确定按钮
        function confirmDialog() {
            // 第一重校验：检查是否有数据
            if (businessData.length === 0) {
                alert('请至少添加一条业务数据！');
                return;
            }
            
            // 第二重校验：检查每行数据是否完整
            for (let i = 0; i < businessData.length; i++) {
                const row = businessData[i];
                if (!row.business || !row.amount) {
                    alert('第' + (i + 1) + '行数据不完整，请检查业务类型和办理量是否都已填写！');
                    return;
                }
                if (parseInt(row.amount) <= 0) {
                    alert('第' + (i + 1) + '行的办理量必须大于0！');
                    return;
                }
            }
            
            // 校验通过，处理业务逻辑
            console.log('提交数据：', {
                type: currentDialogType,
                data: businessData
            });
            
            alert(currentDialogType + '业务登记成功！');
            
            // 清空数据并关闭弹窗
            cancelDialog();
        }
        
        // 点击遮罩层关闭弹窗
        document.addEventListener('click', function(e) {
            if (e.target.classList.contains('dialog-overlay')) {
                closeDialog();
            }
        });
    </script>
</body>
</html>